package com.robusta.cityuate.fragments;

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.robusta.cityuate.R;
import com.robusta.cityuate.activities.FindSpotsMapActivity;
import com.robusta.cityuate.activities.SpotProfileActivity;
import com.robusta.cityuate.adapters.ReservationsListAdapter;
import com.robusta.cityuate.base.CityuateListFragment;
import com.robusta.cityuate.base.ViewType;
import com.robusta.cityuate.objects.Reservation;
import com.robusta.cityuate.objects.Spot;
import com.robusta.cityuate.services.CityuateBroadCastReceiver;
import com.robusta.cityuate.services.GetSpotService;
import com.robusta.cityuate.services.MyReservationsService;
import com.robusta.cityuate.utils.ConnectionUtils;

public class ReservationsListFragment extends CityuateListFragment {

	private Context mContext;

	public enum ReservationType {
		COMING, OLD
	};

	boolean coming = true;

	protected static final String TAG = ReservationsListFragment.class
			.getName();

	private Button retryBtn;
	private ProgressBar progressBar;
	private LinearLayout listPart;
	private ReservationsListAdapter adapter;

	private CityuateBroadCastReceiver receiver = new CityuateBroadCastReceiver() {

		@Override
		public void onSuccess() {
			getReservationsSuccess();
		}

		@Override
		public void onFailure() {
			getReservationsFail();
		}

		@Override
		public void onCancel() {
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
					false);
			ConnectionUtils.clearConnection(mContext, TAG);
		}
	};

	protected static final String DEL_TAG = TAG + "_DEL";

	private static final String CHECK_IN_TAG = TAG + "_CHECK";

	private CityuateBroadCastReceiver deleteReceiver = new CityuateBroadCastReceiver() {

		@Override
		public void onCancel() {
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
					false);
			ConnectionUtils.clearConnection(mContext, DEL_TAG);
		}

		@Override
		public void onSuccess() {
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
					false);
			Toast.makeText(mContext, getString(R.string.reservation_deleted),
					Toast.LENGTH_LONG).show();
			getRerservations();
			ConnectionUtils.clearConnection(mContext, DEL_TAG);
		}

		@Override
		public void onFailure() {
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
					false);
			Toast.makeText(mContext,
					ConnectionUtils.getExtra(mContext, DEL_TAG),
					Toast.LENGTH_LONG).show();
			ConnectionUtils.clearConnection(mContext, DEL_TAG);
		}

	};

	private CityuateBroadCastReceiver checkInReceiver = new CityuateBroadCastReceiver() {

		@Override
		public void onSuccess() {
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
					false);
			Toast.makeText(mContext, getString(R.string.checked_in),
					Toast.LENGTH_LONG).show();

			ConnectionUtils.clearConnection(mContext, CHECK_IN_TAG);
		}

		@Override
		public void onFailure() {
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
					false);
			Toast.makeText(mContext,
					ConnectionUtils.getExtra(mContext, CHECK_IN_TAG),
					Toast.LENGTH_LONG).show();
			ConnectionUtils.clearConnection(mContext, CHECK_IN_TAG);
		}

		@Override
		public void onCancel() {
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
					false);
			ConnectionUtils.clearConnection(mContext, CHECK_IN_TAG);
		}
	};

	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.reservations_list_fragment_view,
				container, false);
		progressBar = (ProgressBar) v.findViewById(R.id.spots_loading);
		listPart = (LinearLayout) v.findViewById(R.id.list_part);
		// show retry button
		retryBtn = (Button) v.findViewById(R.id.retry);

		retryBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// fragmentView.removeView(retryBtn);
				retryBtn.setVisibility(View.GONE);
				ConnectionUtils.clearConnection(mContext, TAG);
				getRerservations();

			}
		});

		return v;

	};

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		// setContentView(R.layout.my_reservations_view);
		mContext = getActivity();
		adapter = new ReservationsListAdapter(mContext);
		setListAdapter(adapter);
		registerForContextMenu(getListView());

	}

	@Override
	public void onResume() {
		super.onResume();
		// register receiver
		mContext.registerReceiver(receiver, new IntentFilter(TAG));
		mContext.registerReceiver(deleteReceiver, new IntentFilter(DEL_TAG));
		mContext.registerReceiver(checkInReceiver, new IntentFilter(
				CHECK_IN_TAG));
		Log.d(TAG, "onResume");
		if (ConnectionUtils.isConnecting(mContext, TAG)) {
			progressBar.setVisibility(View.VISIBLE);
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
					true);
		} else if (ConnectionUtils.wasConnected(mContext, TAG))
			if (ConnectionUtils.isResultSuccessful(mContext, TAG)) {
				receiver.onSuccess();
			} else
				receiver.onFailure();
		else
			getRerservations();

		if (ConnectionUtils.isConnecting(mContext, DEL_TAG)) {
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
					true);
		} else if (ConnectionUtils.wasConnected(mContext, DEL_TAG))
			if (ConnectionUtils.isResultSuccessful(mContext, DEL_TAG))
				deleteReceiver.onSuccess();
			else
				deleteReceiver.onFailure();

		if (ConnectionUtils.isConnecting(mContext, CHECK_IN_TAG)) {
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
					true);
		} else if (ConnectionUtils.wasConnected(mContext, CHECK_IN_TAG))
			if (ConnectionUtils.isResultSuccessful(mContext, CHECK_IN_TAG))
				checkInReceiver.onSuccess();
			else
				checkInReceiver.onFailure();
	}

	@Override
	public void onPause() {
		super.onPause();
		mContext.unregisterReceiver(receiver);
		mContext.unregisterReceiver(deleteReceiver);
		mContext.unregisterReceiver(checkInReceiver);

		if (!ConnectionUtils.isConnecting(mContext, DEL_TAG))
			ConnectionUtils.clearConnection(mContext, DEL_TAG);
		if (!ConnectionUtils.isConnecting(mContext, CHECK_IN_TAG))
			ConnectionUtils.clearConnection(mContext, CHECK_IN_TAG);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.e(TAG, "Oferring List OnDestroy");
		if (!ConnectionUtils.isConnecting(mContext, TAG))
			ConnectionUtils.clearConnection(mContext, TAG);
	}

	private void getRerservations() {

		if (!ConnectionUtils.isNetworkAvailable(mContext))
			ConnectionUtils.showNoConnectionDialog(mContext);
		getSherlockActivity()
				.setSupportProgressBarIndeterminateVisibility(true);
		listPart.setVisibility(View.GONE);
		retryBtn.setVisibility(View.GONE);
		progressBar.setVisibility(View.VISIBLE);
		Intent backgroud_regService = new Intent(mContext,
				MyReservationsService.class);
		backgroud_regService.setAction(TAG);
		backgroud_regService.putExtra(GetSpotService.LOGIN_RQUIRED, true);
		backgroud_regService.putExtra(MyReservationsService.IS_COMING, coming);
		mContext.startService(backgroud_regService);
		Log.e(TAG, "Reservations Service fired");

	}

	/**
	 * success getting offers
	 */
	private void getReservationsSuccess() {
		getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
				false);
		listPart.setVisibility(View.VISIBLE);
		progressBar.setVisibility(View.GONE);

		String josnArrayString = ConnectionUtils.getExtra(mContext, TAG);

		if (josnArrayString == null) {
			Log.e(TAG, "emptylist");
			return;
		}
		try {
			ArrayList<Reservation> reservations = new ArrayList<Reservation>();
			JSONArray resList = new JSONArray(josnArrayString);
			for (int i = 0; i < resList.length(); i++) {
				JSONObject res = resList.getJSONObject(i);
				reservations.add(Reservation.fromJSON(res));
			}
			adapter.upDateEntries(reservations);
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	/**
	 * fail getting offers
	 */
	private void getReservationsFail() {
		getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
				false);
		progressBar.setVisibility(View.GONE);
		retryBtn.setVisibility(View.VISIBLE);

		Toast.makeText(mContext, ConnectionUtils.getExtra(mContext, TAG),
				Toast.LENGTH_LONG).show();
		ConnectionUtils.clearConnection(mContext, TAG);
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		android.view.MenuInflater inflater = getActivity().getMenuInflater();
		inflater.inflate(R.menu.reservations_context_menu, menu);

	}

	@Override
	public boolean onContextItemSelected(android.view.MenuItem item) {
		AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
				.getMenuInfo();
		Reservation res = (Reservation) adapter.getItem(info.position);
		switch (item.getItemId()) {
		case R.id.delete:
			confirmDeleteReservation(res);
			break;
		case R.id.check_in:
			getSherlockActivity().setSupportProgressBarIndeterminateVisibility(
					true);
			res.checkIn(mContext, CHECK_IN_TAG);
			break;
		case R.id.go_to_spot:
			Intent spotProfile = new Intent(mContext, SpotProfileActivity.class);
			spotProfile.putExtra(Spot.SPOT, res.getSpot());
			spotProfile.putExtra(ViewType.VIEWTYPE, ViewType.Type.RENTER);
			startActivity(spotProfile);
			break;

		}
		return super.onContextItemSelected(item);
	}

	private void confirmDeleteReservation(final Reservation res) {
		// Use the Builder class for convenient dialog construction
		AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
		builder.setTitle(getString(R.string.cancel_res_confirm));
		builder.setMessage(R.string.cancel_res_confirm_msg)
				.setPositiveButton(android.R.string.yes,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {

								getSherlockActivity()
										.setSupportProgressBarIndeterminateVisibility(
												true);
								res.delete(mContext, DEL_TAG);
							}
						}).setNegativeButton(android.R.string.no, null);

		builder.show();
	}

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		inflater.inflate(R.menu.my_reservations_option_menu, menu);
		super.onCreateOptionsMenu(menu, inflater);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.refresh:
			getRerservations();
			break;
		case R.id.add:
			mContext.startActivity(new Intent(mContext,
					FindSpotsMapActivity.class));
			break;

		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		final Reservation res = (Reservation) l.getAdapter().getItem(position);
		AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
		builder.setTitle(getString(R.string.check_in));
		builder.setMessage(R.string.do_check_in)
				.setPositiveButton(android.R.string.yes,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {

								getSherlockActivity()
										.setSupportProgressBarIndeterminateVisibility(
												true);
								res.checkIn(mContext, CHECK_IN_TAG);
							}
						}).setNegativeButton(android.R.string.no, null);

		builder.show();

	}

	public static ReservationsListFragment getInstant(ReservationType type) {
		ReservationsListFragment resFrag = new ReservationsListFragment();
		switch (type) {
		case COMING:
			resFrag.coming = true;
			break;

		case OLD:
			resFrag.coming = false;
			break;
		}
		return resFrag;
	}

}
